/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.ohosannotations.test;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;

import org.ohosannotations.annotations.Background;
import org.ohosannotations.annotations.EAbility;
import org.ohosannotations.annotations.UiThread;
import org.ohosannotations.test.ebean.GenericBean;
import org.ohosannotations.test.ebean.SomeBean;
import org.ohosannotations.test.instancestate.MySerializableBean;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;

/**
 * 线程的能力
 * ThreadAbility
 *
 * @author dev
 * @since 2021-06-07
 */
@EAbility
public class ThreadAbility extends Ability {
    /**
     * 连环延误
     */
    public static final long SERIAL_DELAY = 1000L;
    /**
     * 被称为延迟
     */
    public boolean calledDelayed = false;

    /**
     * 在开始
     *
     * @param intent 意图
     */
    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
    }

    /**
     * 空的用户界面的方法
     */
    @UiThread
    void emptyUiMethod() {
    }

    /**
     * 空背景的方法
     */
    @Background
    void emptyBackgroundMethod() {
    }

    /**
     * 空延迟背景的方法
     */
    @Background(delay = 1000)
    void emptyDelayedBackgroundMethod() {
    }

    /**
     * 添加
     *
     * @param list 列表
     * @param i1 i1
     * @param delay 延迟
     * @param sem 扫描电镜
     */
    private void add(List<Integer> list, int i1, int delay, Semaphore sem) {
        try {
            if (delay > 0) {
                Thread.sleep(delay);
            }
            list.add(i1);
            if (sem != null) {
                sem.release();
            }
        } catch (InterruptedException error) {
            // should never happen
        }
    }

    /**
     * 添加背景
     *
     * @param list 列表
     * @param i1 我
     * @param delay 延迟
     * @param sem 扫描电镜
     */
    @Background
    void addBackground(List<Integer> list, int i1, int delay, Semaphore sem) {
        add(list, i1, delay, sem);
    }

    /**
     * 添加序列化的背景
     *
     * @param list 列表
     * @param i1 我
     * @param delay 延迟
     * @param sem 扫描电镜
     */
    @Background(serial = "test")
    void addSerializedBackground(List<Integer> list, int i1, int delay, Semaphore sem) {
        add(list, i1, delay, sem);
    }

    /**
     * 添加可删除的背景
     *
     * @param list 列表
     * @param i1 我
     * @param interruptibleDelay 可中断延迟
     */
    @Background(id = "to_cancel")
    void addCancellableBackground(List<Integer> list, int i1, int interruptibleDelay) {
        add(list, i1, interruptibleDelay, null);
    }

    /**
     * 添加可删除的序列化的背景
     *
     * @param list 列表
     * @param i1 我
     * @param delay 延迟
     */
    @Background(id = "to_cancel_serial", serial = "test")
    void addCancellableSerializedBackground(List<Integer> list, int i1, int delay) {
        add(list, i1, delay, null);
    }

    /**
     * 对象的用户界面方法
     *
     * @param param 参数
     */
    @UiThread
    void objectUiMethod(Object param) {
    }

    /**
     * 对象背景的方法
     *
     * @param param 参数
     */
    @Background
    void objectBackgroundMethod(Object param) {
    }

    /**
     * 通用用户界面的方法
     *
     * @param param 参数
     */
    @UiThread
    void genericUiMethod(List<Map<String, List<Set<Void>>>> param) {
    }

    /**
     * 通用背景的方法
     *
     * @param param 参数
     */
    @Background
    void genericBackgroundMethod(List<Map<String, List<Set<MySerializableBean[]>>>> param) {
    }

    /**
     * 通用背景的方法
     *
     * @param param 参数
     */
    @Background
    void genericBackgroundMethod(Set<? extends GenericBean<? extends SomeBean>> param) {
    }

    /**
     * 空的ui延迟的方法
     */
    @UiThread(delay = 1000)
    void emptyUiDelayedMethod() {
    }

    /**
     * empt ui方法排队
     */
    @UiThread(propagation = UiThread.Propagation.ENQUEUE)
    void emptUiMethodEnqueue() {
    }

    /**
     * empt ui方法重用
     */
    @UiThread(propagation = UiThread.Propagation.ENQUEUE)
    void emptUiMethodReuse() {
    }

    /**
     * ui线程使用数组的目的的方法
     *
     * @param array 数组
     */
    @UiThread
    void uiThreadedUsingArrayParamtersMethod(MySerializableBean[] array) {
    }

    /**
     * ui线程使用数组的目的的方法
     *
     * @param array 数组
     */
    @UiThread
    void uiThreadedUsingArrayParamtersMethod(MySerializableBean[][] array) {
    }

    /**
     * backgroundd使用数组的目的的方法
     *
     * @param array 数组
     */
    @Background
    void backgrounddUsingArrayParamtersMethod(MySerializableBean[] array) {
    }

    /**
     * 背景使用数组的目的的方法
     *
     * @param array 数组
     */
    @Background
    void backgroundUsingArrayParamtersMethod(MySerializableBean[][] array) {
    }

    /**
     * 背景抛出异常
     */
    @Background
    void backgroundThrowException() {
    }

    /**
     * ui线程抛出异常
     */
    @UiThread
    void uiThreadThrowException() {
    }

    /**
     * 调用延迟串行
     *
     * @param callback 回调
     */
    @Background(serial = "foo")
    protected void callDelayedSerial(Runnable callback) {
        delayedSerial(System.currentTimeMillis(), callback);
    }

    /**
     * 延迟串行
     *
     * @param execTime 执行时间
     * @param callback 回调
     */
    @Background(serial = "foo", id = "delayedTask", delay = SERIAL_DELAY)
    protected void delayedSerial(final long execTime, Runnable callback) {
        calledDelayed = System.currentTimeMillis() - execTime >= SERIAL_DELAY;
        callback.run();
    }
}
